feat(save-editor): group and explain the attribute list - #77
Conversation
The attribute list carried MagicianLevel as "Magic Circle" — the exact name the Skills list already uses for the same thing, in the same tab. Only one of the two did anything: the game re-derives the attribute from the skill's GameplayEffect class when the save is loaded, so a value typed into the attribute field never survives. Proven in game: a save whose effect class said circle 6 while MagicianLevel still said -1 let the hero use a circle 4 rune, and rune usability is stated against MagicianLevel. MagicianLevel therefore joins the four Critical_* attributes in heroHiddenAttributeIds, for the same reason they are there. It stays editable in the All-data browser. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0db4ff1421
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
When the typed attribute search fails or comes back empty, the hero pane falls back to the legacy private-player editor, which listed every row the core's summary carries — without consulting heroHiddenAttributeIds. The core includes MagicianLevel in that summary, so on this path the two identically named Magic Circle controls were still both there, the ineffective one included. The four Critical_* ids never surfaced the problem because the core's private-player summary does not carry them at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Chef's kiss. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 8df9e48. Configure here.
|
Codex Review: Didn't find any major issues. You're on a roll. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
The advanced attributes were one long list of raw engine ids with machine-generated labels — "Fill ratio (AttributeSet_Thirst)", "Critical level (%)" — that told a player nothing, and several of them do nothing at all. Grouped into Combat & movement, Diving, Sleep & rest and Intoxication, with the leftovers still under Advanced. A group's sidebar entry only appears when the hero actually carries its attributes. Every remaining value now has a real name and a tooltip on that name saying what it does in the game, in all twelve languages. Both live in one ICU select message per locale, so the whole table is two keys. Ids that exist in several attribute sets are addressed by a composite key (`Health_RecoveryRatePerHourOfSleep`), which is what lets the Health and Mana sleep rates carry different wording — and what retires the "(AttributeSet_X)" suffix the rows used to grow. The separator is an underscore because ICU rejects a dot in a select arm. Dropped from the curated view, because the game does not act on them: Toughness and its three curve coefficients (encumbrance was cut, and carrying is unlimited), and the sixteen hunger/thirst/fatigue values of the survival mode that cannot be switched on. All stay editable in the All-data browser. See docs/reference/survival-mode.md. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Gothic 1 Remake contains a complete hunger/thirst/fatigue system that no player can reach: the abilities are granted, the attribute sets are seeded, the per-stage effects are configured — and the difficulty UI row that would switch it on ships hidden behind m_IsShown = false, with the remaining gate in native code no script ever calls. Writing it down because the save editor now hides sixteen attributes on the strength of it. If a patch switches the mode on, that decision has to be revisited, and nobody should have to redo the investigation to know what those values meant. Covers what it is, why it does not run, what was measured in game, the three places the flag is stored (and the permadeath field sitting next to it), the full mechanics including a mis-wired thirst threshold, the inventory of hidden values, and the steps to re-enable the group. Registered in the reference index and in the MCP page table, so the server can serve it as gore://reference/survival-mode. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: b9ee3af21b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…combat group "XP for executing" and "XP for killing" were nearly the same sentence twice, and neither said what the difference is. Gothic has a non-lethal defeat state: an opponent can be beaten down and left unconscious rather than killed, and finishing off someone who already lies defeated is a separate act the game even tracks as its own crime severity. So the pair is now "XP for defeating" (bringing the character down at all, dead or merely unconscious) against "XP for finishing off" (killing it while it lies defeated), with tooltips that name both outcomes. The combat group was called "Combat skills", which reads as the game's one-handed/two-handed/bow skills. It holds poise, damage taken and movement speed instead, so it is "Combat and movement" now, and the message key follows the meaning. Both across all twelve languages, each translated with its language's established term for a downed opponent and for the finishing blow. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 564b68dc76
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
"Combat and movement" was too wide for the sidebar. It reads "Combat / movement" now, in every language, which is the same information in fewer pixels. The sidebar tile truncated with an ellipsis at one line, so a heading that still does not fit lost its second word entirely. It wraps onto a second line instead; the ellipsis only applies beyond that. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
"Combat / movement" and "Sleep & rest" read as sentence fragments next to the single-word headings. English UI headings take title case, so the second word is capitalised. "Main stats" is carried along for the same reason — it predates this work, but leaving it lower-case would have made the sidebar mix both conventions. Only English changes. German capitalises its nouns regardless, and the other locales use sentence case for headings on purpose. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
… tooltips Two gaps in the curated view for NPCs, both from the set-qualified keys introduced with the grouping work. The NPC path never passed the attribute set into the shared policy, so heroAttributeHidden and heroAttributeGroup only ever saw the bare id. A Fatigue RecoveryRatePerHourOfSleep therefore stayed visible on an NPC although it is inert, and the real Health and Mana rates landed in Advanced instead of Sleep. The panel already recovered the set from the typed path for labels; that logic now lives on NpcAttributeRow itself, where the filter can reach it too, and grouping, ranking, labels and tooltips all take it. The tooltips described what "the hero" absorbs, takes or drinks, but the same strings render on an NPC row, where they claimed the wrong subject. Ten of them now name "this character" instead, in all twelve languages — including a French one whose English original never mentioned the hero at all. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
@codex review |
|
Codex Review: Didn't find any major issues. Nice work! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
@codex review |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 679afce. Configure here.
|
Codex Review: Didn't find any major issues. Another round soon, please! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
The attribute list was a dump of raw engine ids. Some had machine-generated labels that told a player nothing — "Fill ratio (AttributeSet_Thirst)", "Critical level (%)" — several duplicated a control that already existed elsewhere, and a number of them do nothing at all in the game.
Two controls that silently did nothing
MagicianLevelsat in the attribute list under the same name as the Magic Circle row under Skills, in the same tab. Only one of the two worked: the game re-derives the attribute from the skill's GameplayEffect class on load, so a value typed into the field never survived.Proven in game — a save whose effect class said circle 6 while
MagicianLevelstill said-1let the hero use a circle 4 rune, and rune usability is stated againstMagicianLevel(every rune writesm_RequiredStats[MagicianLevel] = RequiredMagicCircleLevel, the same machinery a sword uses for Strength).That makes it the same case as the four
Critical_*attributes, hidden earlier for exactly this reason. It joins them. The same exclusion now also applies on the fallback path, where the legacy private-player editor listed every row the core's summary carries without consulting the hidden set.The advanced list, reworked
Grouped into Combat & movement, Diving, Sleep & rest and Intoxication, with the leftovers under Advanced. A group's sidebar entry only appears when the hero actually carries its attributes.
Every remaining value has a real name and a tooltip on that name saying what it does — in all twelve languages. Both live in one ICU
selectmessage per locale, so the whole table is two keys rather than fifty.Ids that exist in several attribute sets are addressed by a composite key (
Health_RecoveryRatePerHourOfSleep). That is what lets the Health and Mana sleep rates carry different wording, and what retires the(AttributeSet_X)suffix the rows used to grow.Values dropped, and why
Toughness,ToughnessA/B/CBoth stay editable in the All-data browser — the editor hides what cannot work, it does not refuse access to the bytes.
The survival finding is written up in
docs/reference/survival-mode.md: the system is fully built and the six abilities are granted, but the difficulty UI row that would enable it ships hidden behindm_IsShown = falseand the remaining gate is native code no script ever calls. Forcing the runtime state true before the hero loaded, with hunger at 900/1000 — the stage that owes −15 % Strength and 1 HP per second — changed nothing. The page records the mechanics, the three places the flag is stored (and the permadeath field sitting next to it), the inventory of hidden values and the steps to re-enable the group, so the decision can be revisited without redoing the investigation.Testing
flutter test— 541 passed.flutter analyze lib test— no issues.cargo test -p gore-mcp— 310 passed.🤖 Generated with Claude Code
Note
Low Risk
UI and save-field presentation only; edit paths are unchanged and hidden attributes remain reachable via All data.
Overview
Reworks the curated hero/NPC attribute UI so advanced stats are grouped (Combat / movement, Diving, Sleep & rest, Intoxication, plus Advanced), with localized display names and hover tooltips wired through
heroAttributeKeyand newattributeManualTooltipstrings in all supported locales.Hiding policy is centralized in
heroAttributeHidden(set-aware): drops duplicate or game-derived fields such asMagicianLevel(second “Magic Circle”), unused toughness encumbrance stats, and hunger/thirst/fatigue survival values (still editable under All data). Combat sidebar now surfaces real poise/movement stats instead of an empty combat-skills bucket.Player typed view, NPC panel, and the legacy private-player attribute list all share the same grouping, filtering, and tooltip plumbing; sidebar labels can wrap to two lines for longer group titles.
Reviewed by Cursor Bugbot for commit 679afce. Bugbot is set up for automated code reviews on this repo. Configure here.